namespace Agile.Genie.Descriptors
{
    using System;
    using System.Data;
    using Agile.Common;

    /// <summary>
    /// Contains specific details for the requested stored
    /// procedure and table.
    /// This class has no dependencies on the type of code
    /// that is being generated!
    /// 
    /// Contains info such as:
    ///     - stored procedure name
    ///     - parameters
    ///     - parameter details (eg name, datatype)
    /// </summary>
    public class StoredProcedure
    {
        #region Constructors and Initializers

        /// <summary>
        /// Instantiates a new Stored Procedure object
        /// </summary>
        /// <param name="table">Table that the stored procedure is for</param>
        /// <param name="storedProcedureType">The type of stored procedure</param>
        private StoredProcedure(DatabaseTable table, string storedProcedureType)
        {
            Asserts.IsNotNull("table", table);
            Asserts.IsNotNull("storedProcedureType", storedProcedureType);
            _table = table;
        }

        /// <summary>
        /// Instantiate a new StoreProcedure object 
        /// for the given table.
        /// </summary>
        /// <param name="table">The table to derive the stored
        /// procedure information from.</param>
        /// <returns></returns>
        public static StoredProcedure InstantiateSelect(DatabaseTable table)
        {
            return new StoredProcedure(table, "Select");
        }

        #endregion

        #region Private members

        private DatabaseTable _table;

        #endregion

        #region Public Properties

        private StoredProcedureParameterCollection _parameters = null;

        /// <summary>
        /// All of the parameters for this stored procedure
        /// </summary>
        public StoredProcedureParameterCollection Parameters
        {
            get { return _parameters; }
        }


//        /// <summary>
//        /// Gets the column name with the @ symbol at the front.
//        /// Removes spaces from the column name if there are any.
//        /// </summary>
//        /// <remarks>Useful for stored procedure parameters</remarks>
//        public string StoredProcedureParameterName
//        {
//            get
//            {
//                if(Name.Substring(0, 1) != "@")
//                {
//                    return "@" + GenieToolbox.RemoveUnsafeCharactersFromString(Name);
//                }
//                else
//                {
//                    return GenieToolbox.RemoveUnsafeCharactersFromString(Name);
//                }
//            }
//        }

        #endregion

        private DataTable _storedProcedurePermissions = null;

        /// <summary>
        /// NOT Implemented.
        /// Gets stored the procedure permissons from sql server.
        /// </summary>
        /// <remarks>return of datatable to be changed.</remarks>
        protected DataTable Permissions
        { // TODO: get rid of datatable
            get
            {
                if (_storedProcedurePermissions != null)
                    return _storedProcedurePermissions;
                throw new NotImplementedException("Permissions - has not yet been implemented.");
            }
        }

        #region Static Functions

        /// <summary>
        /// Checks if the field is an identity or computed field. 
        /// </summary>
        /// <param name="fieldToTest">The TableColumn that is to be tested for inclusion</param>
        /// <returns>False if field is an identity or computed field</returns>
        private static bool IncludeFieldForInsertAndUpdate(TableColumn fieldToTest)
        {
            // Don't genertate the field if it is an identity field
            if (fieldToTest.IsIdentity) return false;
            //Don't generate the field for inserts or updates if it is a computed column.
            if (fieldToTest.IsComputed) return false;

            // Return true for everything else.
            return true;
        }

        #endregion
    }
}